package com.wash.shoes.domain.mtbusy;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lop.open.api.sdk.LopException;
import com.meituan.sdk.MeituanResponse;
import com.meituan.sdk.model.ddzh.yuding.bookresultcallback.BookresultcallbackRequest;
import com.meituan.sdk.model.ddzhkh.dingdan.orderReserveorderquery.OrderReserveorderqueryRequest;
import com.meituan.sdk.model.ddzhkh.dingdan.orderReserveorderquery.OrderReserveorderqueryResponse;
import com.meituan.sdk.model.ddzhkh.dingdan.orderReserveorderquery.ResultSub;
import com.ruoyi.common.utils.StringUtils;
import com.wash.shoes.common.enums.OrderStatusEnum;
import com.wash.shoes.domain.dto.MtOrderProduct;
import com.wash.shoes.domain.dto.MtOrderReserve;
import com.wash.shoes.domain.dto.MtUserAddress;
import com.wash.shoes.domain.jd.JdCreateOrder;
import com.wash.shoes.domain.order.SaveOrderComponent;
import com.wash.shoes.domain.vo.MtPushMessage;
import com.wash.shoes.entity.*;
import com.wash.shoes.exception.WashException;
import com.wash.shoes.helper.FactoryAddressHelper;
import com.wash.shoes.resp.ShopAndFactoryPair;
import com.wash.shoes.service.CustomerService;
import com.wash.shoes.service.UserBlackListService;
import com.wash.shoes.util.AddressCuttingUtil;
import com.wash.shoes.util.CodeUtil;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author lijianguo
 * @Date 16/09/2024
 * 开始预订
 **/
@Log4j2
@Component
public class Mt5810017Busy extends AbstractMtCallback {

    @Autowired
    JdCreateOrder jdCreateOrder;

    @Autowired
    CustomerService customerService;

    @Autowired
    UserBlackListService userBlackListService;

    @Override
    public MtCallbackEnum getType() {
        return MtCallbackEnum.MT_5810017;
    }

    @Override
    @Transactional
    public Integer processBusy(MtPushMessage message, String token, String developerId) {
        CodeUtil.clearCurrentCacheCode();
        MtOrderReserve mtOrderInfo = JSONObject.parseObject(message.getMessage(), MtOrderReserve.class);
        try {
            OrderPo orderPo = processBefore(message, token, mtOrderInfo, developerId);
            bookResult(mtOrderInfo, 2L, 200L, orderPo.getOrderNo(), getToken58(message.getOpBizCode()), developerId);
            // 用户信息落库
            saveCustomInfo(mtOrderInfo);
        } catch (Exception e) {
            // https://developer.meituan.com/docs/biz/comm-errcode1
            log.error(e);
            bookResult(mtOrderInfo, 3L, 808L, null, getToken58(message.getOpBizCode()), developerId);
            throw new WashException(e.getMessage());
        }
        return 1;
    }

    /**
     * @author lijianguo
     * @Date 22/09/2024
     * 用户信息落库
     **/
    private void saveCustomInfo(MtOrderReserve mtOrderInfo) {
        // 用户地址落库不影响其他的业务
        try {
            MtUserAddress mtUserAddress = JSONObject.parseObject(mtOrderInfo.getUserAddress(), MtUserAddress.class);
            CustomerPo customerPo = customerService.getByPhone(mtUserAddress.getReceiverMobile());
            if (Objects.nonNull(customerPo)) {
                return;
            }
            customerPo = new CustomerPo();
            log.info("[用户信息落库]用户不存在，为新用户需要落库，用户电话：" + mtUserAddress.getReceiverMobile());
            List<String> infoList = AddressCuttingUtil.addressCutting(mtUserAddress.getReceiverAddress());
            log.info("美团数据为：" + mtUserAddress.toString());
            customerPo.setName(mtUserAddress.getReceiverName());
            customerPo.setPhone(mtUserAddress.getReceiverMobile());
            customerPo.setAddress(mtUserAddress.getReceiverAddress());
            customerPo.setOrderNum(1);
            customerPo.setStatus(1);
            customerPo.setProvinces(infoList.get(0));
            customerPo.setCity(infoList.get(1));
            customerPo.setCountry(infoList.get(2));
            customerService.save(customerPo);
        } catch (Exception e) {
            log.error(e);
            log.error("用户信息落库异常!");

        }
    }

    /**
     * @author lijianguo
     * @Date 18/09/2024
     * 预订结果回调
     **/
    private void bookResult(MtOrderReserve mtOrderInfo, Long bookStatus, Long code, String appOrderId, String token, String developerId) {

        BookresultcallbackRequest request = new BookresultcallbackRequest();
        request.setOrderId(mtOrderInfo.getOrderId());
        request.setBookStatus(bookStatus);
        request.setCode(code);
        request.setType(2L);
        if (appOrderId != null) {
            request.setAppOrderId(appOrderId);
        }
        try {
            MeituanResponse mtResponse = MtAllClient.getClient(developerId).invokeApi(request, token);
            log.info("mt bookResult request is {}", JSONObject.toJSONString(request));
            log.info("mt bookResult response is {}", JSONObject.toJSONString(mtResponse));
            if (!mtResponse.isSuccess()) {
                throw new WashException(mtResponse.getMsg());
            }
        } catch (Exception e) {
            log.error(e);
            throw new WashException(e.getMessage());
        }
    }
    @Autowired
    private SaveOrderComponent saveOrderComponent;
    @Autowired
    private FactoryAddressHelper factoryAddressHelper;
    /**
     * @author lijianguo
     * @Date 18/09/2024
     * 处理订单，发送快递
     **/
    private OrderPo processBefore(MtPushMessage message, String token, MtOrderReserve mtOrderInfo, String developerId) throws LopException {
        //判断是否命中黑名单
        if (isHitBlacklist(mtOrderInfo.getMobile())) {
            log.error("用户已经被拉黑命中黑名单,用户电话号码为,Mobile = {}", mtOrderInfo.getMobile());
            throw new WashException("用户已经被拉黑命中黑名单,用户电话号码为: " + mtOrderInfo.getMobile());
        }

        List<MtOrderProduct> orderProductList = JSONArray.parseArray(mtOrderInfo.getProducts(), MtOrderProduct.class);
        // 设置订单的商品信息,本系统只有一个sku
        MtOrderProduct mtOrderProduct = orderProductList.get(0);
        // sku id 匹配
        ShopGoodsPo shopGoodsPoDb = shopGoodsService.getBySkuId(mtOrderProduct.getApp_sku_id());
        // 商品名字匹配
        if (shopGoodsPoDb == null) {
            shopGoodsPoDb = shopGoodsService.getByName(mtOrderInfo.getProductName(), 1);
        }
        if (shopGoodsPoDb == null) {
            log.error("商品信息不存在: SKU ID = {}, 商品名称 = {}", mtOrderProduct.getApp_sku_id(), mtOrderInfo.getProductName());
            throw new WashException("商品信息不存在，请在系统配置商品: " + mtOrderProduct.getApp_sku_id() + " : " + mtOrderInfo.getProductName());
        }
        // 销售数量加一
        shopGoodsPoDb.setSalesNum(shopGoodsPoDb.getSalesNum() + 1);
        shopGoodsService.updateById(shopGoodsPoDb);
        MtUserAddress mtUserAddress = JSONObject.parseObject(mtOrderInfo.getUserAddress(), MtUserAddress.class);
        MtUserAddress deliveryAddress = JSONObject.parseObject(mtOrderInfo.getDeliveryAddress(), MtUserAddress.class);
        if (StrUtil.isBlank(deliveryAddress.getReceiverMobile())) {
            // 如果寄件地址不存在，就用用户的地址 记录寄件的地址，以后回寄送的时候用这个地址
            deliveryAddress = mtUserAddress;
        }
        // 查询订单的店铺名字
        OrderReserveorderqueryRequest orderQueryorderRequest = new OrderReserveorderqueryRequest();
        orderQueryorderRequest.setOrderIds(Arrays.asList(Long.valueOf(mtOrderInfo.getOrderId())));
        MeituanResponse<OrderReserveorderqueryResponse> meituanResponse = null;
        ShopPo shopPo;
        ResultSub resultSub;

        try {
            meituanResponse = MtAllClient.getClient(developerId).invokeApi(orderQueryorderRequest, token);
            OrderReserveorderqueryResponse orderQueryorderResponse = meituanResponse.getData();
            resultSub = orderQueryorderResponse.getResult().get(0);
            shopPo = shopService.getShopByName(resultSub.getShopName());
        } catch (Exception e) {
            log.error(e);
            throw new WashException("订单查询失败");
        }
        // 需要再次查询数据库,美团返回的订单信息查询不到
        if (shopPo == null) {
            shopPo = shopService.getByOpBizCode(message.getOpBizCode());
        }
        Assert.notNull(shopPo, "店铺信息不存在,opBizCode = " + message.getOpBizCode());
        // 根据店铺的省市区获取对应的工厂的收货地址
        FactoryPo factoryPo = factoryAddressHelper.getFactoryAddressWithShopAddress(shopPo.getProvincesName(),
                shopPo.getCityName(), shopPo.getCountryName(),shopPo.getBrandId());
/*        ShopAndFactoryPair shopAndFactoryPair =new ShopAndFactoryPair();
        shopAndFactoryPair.setFactoryPo(factoryPo);
        shopAndFactoryPair.setShopPo(shopPo);*/
                /* saveOrderComponent.getShopPoWithMt(mtUserAddress.getReceiverAddress());*/
        // 订单处理
        CustomerPo customerPo = customerService.getByPhone(mtOrderInfo.getMobile());
        OrderPo orderPo = new OrderPo();
        orderPo.setShopId(shopPo.getId());
        if (customerPo != null) {
            orderPo.setCustomId(customerPo.getId());
        }
        // 工厂id
        orderPo.setFactoryId(factoryPo.getId());
        orderPo.setWashFactory(factoryPo.getFactoryName());
        orderPo.setWashShop(shopPo.getShopName());
        orderPo.setCustomPhone(mtOrderInfo.getMobile());
        orderPo.setOrderNo(CodeUtil.getOrderCodeNext("O", shopPo.getId(), shopPo.getShopCode()));
        orderPo.setComeFrom("2");
        orderPo.setShoeNum(Integer.parseInt(mtOrderInfo.getQuantity()) * shopGoodsPoDb.getShoesNum());
        orderPo.setTotalPrice(Double.valueOf(mtOrderInfo.getAmount()));
        orderPo.setOrderPrice(orderPo.getTotalPrice());
        orderPo.setDiscountRatio(0.0);
        // 线上订单状态为取鞋中
        orderPo.setStatus(OrderStatusEnum.PICK_UP_SHOES.getStatus());
        orderPo.setMtBeginTime(mtOrderInfo.getBegintime());
        orderPo.setMtOrderId(mtOrderInfo.getOrderId());
        orderPo.setMtUniOrderId(resultSub.getUniOrderId());
        orderPo.setMtSerialNumbers(resultSub.getSerialNumbers());
        orderPo.setCustomerRemark(mtOrderInfo.getComment());
        orderPo.setShopGoodsUrl(shopGoodsPoDb.getUrl());
        orderPo.setBrandId(shopPo.getBrandId());
        orderService.save(orderPo);
        log.info("保存订单成功订单的id为 {}", orderPo.getOrderNo());

        // 订单的商品
        OrderGoodPo orderGoodPo = new OrderGoodPo();
        orderGoodPo.setShopId(shopPo.getId());
        orderGoodPo.setGoodsId(shopGoodsPoDb.getId());
        orderGoodPo.setName(shopGoodsPoDb.getName());
        orderGoodPo.setPrice(shopGoodsPoDb.getPrice());
        orderGoodPo.setBuyNum(Integer.parseInt(mtOrderInfo.getQuantity()));
        orderGoodPo.setGoodsId(shopGoodsPoDb.getId());
        orderGoodPo.setShoesNum(shopGoodsPoDb.getShoesNum());
        orderGoodPo.setWashType(shopGoodsPoDb.getWashType());
        orderGoodPo.setShopGoodsUrl(shopGoodsPoDb.getUrl());
        orderGoodPo.setOrderId(orderPo.getId());
        orderGoodPo.setRemark("美团购买的商品");
        orderGoodService.save(orderGoodPo);
        log.info("保存订单的商品成功 {}", orderGoodPo.getId());


        //二次分拣清洗地址处理
        //1、有衣鞋的单子寄一个地方，全是鞋子的寄一个地方
        //2、如果是寄到工厂的就获取清洗地址
        MtUserAddress shopAddress = AddressCuttingUtil.getDeliveryAddress(orderGoodPo, shopPo);

        // TODO: 2024/9/17 第二期京东下单，通过发消息异步去下物流单
       /* MtUserAddress shopAddress = new MtUserAddress();
        shopAddress.setReceiverName(shopPo.getShopName());
        shopAddress.setReceiverMobile(shopPo.getPhone());
        StringBuilder fullAddress = new StringBuilder();
        fullAddress.append(shopPo.getProvincesName());
        fullAddress.append(shopPo.getCityName());
        fullAddress.append(shopPo.getCountryName());
        fullAddress.append(shopPo.getAddress());
        shopAddress.setReceiverAddress(fullAddress.toString());*/

        DateTime dateTime = DateUtil.parse(mtOrderInfo.getBegintime(), "yyyy-MM-dd HH:mm");
        long seconds = dateTime.toInstant().getEpochSecond();
        OrderTransportPo orderTransportPo = jdCreateOrder.process(orderPo, mtUserAddress, shopAddress, "取鞋", seconds);
        // 设置地址
        if (deliveryAddress != null) {
            orderTransportPo.setDeliveryJson(JSONObject.toJSONString(deliveryAddress));
        }
        orderTransportService.saveOrUpdate(orderTransportPo);
        return orderPo;
    }

    /**
     * 判读是否命中黑名单
     *
     * @param mobile
     * @return
     */
    private boolean isHitBlacklist(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return false;
        }
        List<UserBlacklistPo> blacklistPos = userBlackListService.queryBlacklistByPhoneNumber(mobile);
        if (!CollectionUtils.isEmpty(blacklistPos)) {
            return true;
        }
        return false;
    }
}
